package online.inote.naruto.api.access.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.log4j.Log4j2;
import online.inote.naruto.api.access.props.ApiAccessProperties;
import online.inote.naruto.utils.DateTimeUtils;

import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
import java.util.Map;

/**
 * @description JWT助手
 * @author XQF.Sui
 * @date 2021/07/30 17:49
 */
@Log4j2
public class JwtHelper {

  public static String genToken(Map<String, Object> claimMap) {
    return Jwts.builder()
        .addClaims(claimMap)
        .setIssuer(ApiAccessProperties.props().getToken().getIssuer())
        .setIssuedAt(DateTimeUtils.getNow())
        .signWith(SignatureAlgorithm.HS256, genKey())
        .compact();
  }

  public static String genToken(
      String id, String username, Map<String, Object> claimMap, Date createTime) {
    return genToken(id, username, claimMap, createTime, null);
  }

  public static String genToken(
      String id, String username, Map<String, Object> claimMap, Date createTime, Date expireTime) {

    if (log.isDebugEnabled()) {
      log.debug(
          "genToken [ id:{} ], [ username:{} ], [ claimMap:{} ], [ createTime:{} ], [ expireTime:{} ]",
          id,
          username,
          claimMap,
          createTime,
          expireTime);

      Key key = genKey();

      log.debug(
          "genToken [ Issuer:{} ], [ genKey:{} ]",
          ApiAccessProperties.props().getToken().getIssuer(),
          key.getAlgorithm() + "|" + key.getFormat() + "|" + key.getEncoded().toString());
    }

    return Jwts.builder()
        .setId(id)
        .setAudience(username)
        .addClaims(claimMap)
        .setIssuer(ApiAccessProperties.props().getToken().getIssuer())
        .setIssuedAt(createTime)
        .setExpiration(expireTime)
        .signWith(SignatureAlgorithm.HS256, genKey())
        .compact();
  }

  public static Key genKey() {
    return new SecretKeySpec(
        ApiAccessProperties.props().getToken().getSecretKey().getBytes(),
        SignatureAlgorithm.HS256.getJcaName());
  }

  public static Jws<Claims> getClaims(String token) {
    return Jwts.parser().setSigningKey(genKey()).parseClaimsJws(token);
  }
}
